home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / net / socket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  27.4 KB  |  1,083 lines

  1. /*
  2.  * NET        An implementation of the SOCKET network access protocol.
  3.  *
  4.  * Version:    @(#)socket.c    1.0.5    05/25/93
  5.  *
  6.  * Authors:    Orest Zborowski, <obz@Kodak.COM>
  7.  *        Ross Biro, <bir7@leland.Stanford.Edu>
  8.  *        Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  9.  *
  10.  * Fixes:
  11.  *        Anonymous    :    NOTSOCK/BADF cleanup. Error fix in
  12.  *                    shutdown()
  13.  *        Alan Cox    :    verify_area() fixes
  14.  *
  15.  *
  16.  *        This program is free software; you can redistribute it and/or
  17.  *        modify it under the terms of the GNU General Public License
  18.  *        as published by the Free Software Foundation; either version
  19.  *        2 of the License, or (at your option) any later version.
  20.  */
  21.  
  22. #include <linux/config.h>
  23. #include <linux/signal.h>
  24. #include <linux/errno.h>
  25. #include <linux/sched.h>
  26. #include <linux/kernel.h>
  27. #include <linux/major.h>
  28. #include <linux/stat.h>
  29. #include <linux/socket.h>
  30. #include <linux/fcntl.h>
  31. #include <linux/termios.h>
  32. #include <linux/net.h>
  33. #include <linux/ddi.h>
  34.  
  35. #include <asm/system.h>
  36. #include <asm/segment.h>
  37.  
  38. #undef SOCK_DEBUG
  39.  
  40. #ifdef SOCK_DEBUG
  41. #include <stdarg.h>
  42. #define DPRINTF(x) dprintf x
  43. #else
  44. #define DPRINTF(x) /**/
  45. #endif
  46.  
  47. static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
  48.               int whence);
  49. static int sock_read(struct inode *inode, struct file *file, char *buf,
  50.              int size);
  51. static int sock_write(struct inode *inode, struct file *file, char *buf,
  52.               int size);
  53. static int sock_readdir(struct inode *inode, struct file *file,
  54.             struct dirent *dirent, int count);
  55. static void sock_close(struct inode *inode, struct file *file);
  56. static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable);
  57. static int sock_ioctl(struct inode *inode, struct file *file,
  58.               unsigned int cmd, unsigned long arg);
  59.  
  60.  
  61. static struct file_operations socket_file_ops = {
  62.   sock_lseek,
  63.   sock_read,
  64.   sock_write,
  65.   sock_readdir,
  66.   sock_select,
  67.   sock_ioctl,
  68.   NULL,            /* mmap */
  69.   NULL,            /* no special open code... */
  70.   sock_close
  71. };
  72. struct socket sockets[NSOCKETS];
  73. static struct wait_queue *socket_wait_free = NULL;
  74. static struct proto_ops *pops[NPROTO];
  75. static int net_debug = 0;
  76.  
  77.  
  78. #ifdef SOCK_DEBUG
  79. /* Module debugging. */
  80. static void
  81. dprintf(int level, char *fmt, ...)
  82. {
  83.   char buff[1024];
  84.   va_list args;
  85.   extern int vsprintf(char * buf, const char * fmt, va_list args);
  86.  
  87.   if (level == 0) return;
  88.   va_start(args, fmt);
  89.   vsprintf(buff, fmt, args);
  90.   va_end(args);
  91.   printk(buff);
  92. }
  93. #endif
  94.  
  95. /* Obtains the first available file descriptor and sets it up for use. */
  96. static int
  97. get_fd(struct inode *inode)
  98. {
  99.   int fd;
  100.   struct file *file;
  101.  
  102.   /* Find a file descriptor suitable for return to the user. */
  103.   file = get_empty_filp();
  104.   if (!file) return(-1);
  105.   for (fd = 0; fd < NR_OPEN; ++fd)
  106.     if (!current->filp[fd]) break;
  107.   if (fd == NR_OPEN) {
  108.     file->f_count = 0;
  109.     return(-1);
  110.   }
  111.   FD_CLR(fd, ¤t->close_on_exec);
  112.   current->filp[fd] = file;
  113.   file->f_op = &socket_file_ops;
  114.   file->f_mode = 3;
  115.   file->f_flags = 0;
  116.   file->f_count = 1;
  117.   file->f_inode = inode;
  118.   if (inode) inode->i_count++;
  119.   file->f_pos = 0;
  120.   return(fd);
  121. }
  122.  
  123.  
  124. /*
  125.  * Reverses the action of get_fd() by releasing the file. it closes
  126.  * the descriptor, but makes sure it does nothing more. Called when
  127.  * an incomplete socket must be closed, along with sock_release().
  128.  */
  129. static inline void
  130. toss_fd(int fd)
  131. {
  132.   sys_close(fd);        /* the count protects us from iput */
  133. }
  134.  
  135.  
  136. struct socket *
  137. socki_lookup(struct inode *inode)
  138. {
  139.   struct socket *sock;
  140.  
  141.   for (sock = sockets; sock <= last_socket; ++sock)
  142.     if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) return(sock);
  143.   return(NULL);
  144. }
  145.  
  146.  
  147. static inline struct socket *
  148. sockfd_lookup(int fd, struct file **pfile)
  149. {
  150.   struct file *file;
  151.  
  152.   if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd])) return(NULL);
  153.   if (pfile) *pfile = file;
  154.   return(socki_lookup(file->f_inode));
  155. }
  156.  
  157.  
  158. static struct socket *
  159. sock_alloc(int wait)
  160. {
  161.   struct socket *sock;
  162.  
  163.   while (1) {
  164.     cli();
  165.     for (sock = sockets; sock <= last_socket; ++sock) {
  166.         if (sock->state == SS_FREE) {
  167.             sock->state = SS_UNCONNECTED;
  168.             sti();
  169.             sock->flags = 0;
  170.             sock->ops = NULL;
  171.             sock->data = NULL;
  172.             sock->conn = NULL;
  173.             sock->iconn = NULL;
  174.  
  175.             /*
  176.              * This really shouldn't be necessary, but everything
  177.              * else depends on inodes, so we grab it.
  178.              * Sleeps are also done on the i_wait member of this
  179.              * inode.  The close system call will iput this inode
  180.              * for us.
  181.              */
  182.             if (!(SOCK_INODE(sock) = get_empty_inode())) {
  183.                 printk("NET: sock_alloc: no more inodes\n");
  184.                 sock->state = SS_FREE;
  185.                 return(NULL);
  186.             }
  187.             SOCK_INODE(sock)->i_mode = S_IFSOCK;
  188.             SOCK_INODE(sock)->i_uid = current->euid;
  189.             SOCK_INODE(sock)->i_gid = current->egid;
  190.  
  191.             sock->wait = &SOCK_INODE(sock)->i_wait;
  192.             DPRINTF((net_debug,
  193.                 "NET: sock_alloc: sk 0x%x, ino 0x%x\n",
  194.                                    sock, SOCK_INODE(sock)));
  195.             return(sock);
  196.         }
  197.     }
  198.     sti();
  199.     if (!wait) return(NULL);
  200.     DPRINTF((net_debug, "NET: sock_alloc: no free sockets, sleeping...\n"));
  201.     interruptible_sleep_on(&socket_wait_free);
  202.     if (current->signal & ~current->blocked) {
  203.         DPRINTF((net_debug, "NET: sock_alloc: sleep was interrupted\n"));
  204.         return(NULL);
  205.     }
  206.     DPRINTF((net_debug, "NET: sock_alloc: wakeup... trying again...\n"));
  207.   }
  208. }
  209.  
  210.  
  211. static inline void
  212. sock_release_peer(struct socket *peer)
  213. {
  214.   peer->state = SS_DISCONNECTING;
  215.   wake_up(peer->wait);
  216. }
  217.  
  218.  
  219. static void
  220. sock_release(struct socket *sock)
  221. {
  222.   int oldstate;
  223.   struct socket *peersock, *nextsock;
  224.  
  225.   DPRINTF((net_debug, "NET: sock_release: socket 0x%x, inode 0x%x\n",
  226.                         sock, SOCK_INODE(sock)));
  227.   if ((oldstate = sock->state) != SS_UNCONNECTED)
  228.             sock->state = SS_DISCONNECTING;
  229.  
  230.   /* Wake up anyone waiting for connections. */
  231.   for (peersock = sock->iconn; peersock; peersock = nextsock) {
  232.     nextsock = peersock->next;
  233.     sock_release_peer(peersock);
  234.   }
  235.  
  236.   /*
  237.    * Wake up anyone we're connected to. First, we release the
  238.    * protocol, to give it a chance to flush data, etc.
  239.    */
  240.   peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
  241.   if (sock->ops) sock->ops->release(sock, peersock);
  242.   if (peersock) sock_release_peer(peersock);
  243.   sock->state = SS_FREE;        /* this really releases us */
  244.   wake_up(&socket_wait_free);
  245.  
  246.   /* We need to do this. If sock alloc was called we already have an inode. */
  247.   iput(SOCK_INODE(sock));
  248. }
  249.  
  250.  
  251. static int
  252. sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
  253. {
  254.   DPRINTF((net_debug, "NET: sock_lseek: huh?\n"));
  255.   return(-ESPIPE);
  256. }
  257.  
  258.  
  259. static int
  260. sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
  261. {
  262.   struct socket *sock;
  263.  
  264.   DPRINTF((net_debug, "NET: sock_read: buf=0x%x, size=%d\n", ubuf, size));
  265.   if (!(sock = socki_lookup(inode))) {
  266.     printk("NET: sock_read: can't find socket for inode!\n");
  267.     return(-EBADF);
  268.   }
  269.   if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
  270.   return(sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK)));
  271. }
  272.  
  273.  
  274. static int
  275. sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
  276. {
  277.   struct socket *sock;
  278.  
  279.   DPRINTF((net_debug, "NET: sock_write: buf=0x%x, size=%d\n", ubuf, size));
  280.   if (!(sock = socki_lookup(inode))) {
  281.     printk("NET: sock_write: can't find socket for inode!\n");
  282.     return(-EBADF);
  283.   }
  284.   if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
  285.   return(sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)));
  286. }
  287.  
  288.  
  289. static int
  290. sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
  291.          int count)
  292. {
  293.   DPRINTF((net_debug, "NET: sock_readdir: huh?\n"));
  294.   return(-EBADF);
  295. }
  296.  
  297.  
  298. int
  299. sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
  300.        unsigned long arg)
  301. {
  302.   struct socket *sock;
  303.  
  304.   DPRINTF((net_debug, "NET: sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n",
  305.                             inode, cmd, arg));
  306.   if (!(sock = socki_lookup(inode))) {
  307.     printk("NET: sock_ioctl: can't find socket for inode!\n");
  308.     return(-EBADF);
  309.   }
  310.   return(sock->ops->ioctl(sock, cmd, arg));
  311. }
  312.  
  313.  
  314. static int
  315. sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
  316. {
  317.   struct socket *sock;
  318.  
  319.   DPRINTF((net_debug, "NET: sock_select: inode = 0x%x, kind = %s\n", inode,
  320.        (sel_type == SEL_IN) ? "in" :
  321.        (sel_type == SEL_OUT) ? "out" : "ex"));
  322.   if (!(sock = socki_lookup(inode))) {
  323.     printk("NET: sock_select: can't find socket for inode!\n");
  324.     return(0);
  325.   }
  326.  
  327.   /* We can't return errors to select, so its either yes or no. */
  328.   if (sock->ops && sock->ops->select)
  329.     return(sock->ops->select(sock, sel_type, wait));
  330.   return(0);
  331. }
  332.  
  333.  
  334. void
  335. sock_close(struct inode *inode, struct file *file)
  336. {
  337.   struct socket *sock;
  338.  
  339.   DPRINTF((net_debug, "NET: sock_close: inode=0x%x (cnt=%d)\n",
  340.                         inode, inode->i_count));
  341.  
  342.   /* It's possible the inode is NULL if we're closing an unfinished socket. */
  343.   if (!inode) return;
  344.   if (!(sock = socki_lookup(inode))) {
  345.     printk("NET: sock_close: can't find socket for inode!\n");
  346.     return;
  347.   }
  348.   sock_release(sock);
  349. }
  350.  
  351.  
  352. int
  353. sock_awaitconn(struct socket *mysock, struct socket *servsock)
  354. {
  355.   struct socket *last;
  356.  
  357.   DPRINTF((net_debug,
  358.     "NET: sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
  359.                             mysock, servsock));
  360.   if (!(servsock->flags & SO_ACCEPTCON)) {
  361.     DPRINTF((net_debug,
  362.         "NET: sock_awaitconn: server not accepting connections\n"));
  363.     return(-EINVAL);
  364.   }
  365.  
  366.   /* Put ourselves on the server's incomplete connection queue. */
  367.   mysock->next = NULL;
  368.   cli();
  369.   if (!(last = servsock->iconn)) servsock->iconn = mysock;
  370.     else {
  371.     while (last->next) last = last->next;
  372.     last->next = mysock;
  373.   }
  374.   mysock->state = SS_CONNECTING;
  375.   mysock->conn = servsock;
  376.   sti();
  377.  
  378.   /*
  379.    * Wake up server, then await connection. server will set state to
  380.    * SS_CONNECTED if we're connected.
  381.    */
  382.   wake_up(servsock->wait);
  383.   if (mysock->state != SS_CONNECTED) {
  384.     interruptible_sleep_on(mysock->wait);
  385.     if (mysock->state != SS_CONNECTED &&
  386.         mysock->state != SS_DISCONNECTING) {
  387.         /*
  388.          * if we're not connected we could have been
  389.          * 1) interrupted, so we need to remove ourselves
  390.          *    from the server list
  391.          * 2) rejected (mysock->conn == NULL), and have
  392.          *    already been removed from the list
  393.          */
  394.         if (mysock->conn == servsock) {
  395.             cli();
  396.             if ((last = servsock->iconn) == mysock)
  397.                     servsock->iconn = mysock->next;
  398.             else {
  399.                 while (last->next != mysock) last = last->next;
  400.                 last->next = mysock->next;
  401.             }
  402.             sti();
  403.         }
  404.         return(mysock->conn ? -EINTR : -EACCES);
  405.     }
  406.   }
  407.   return(0);
  408. }
  409.  
  410.  
  411. /*
  412.  * Perform the socket system call. we locate the appropriate
  413.  * family, then create a fresh socket.
  414.  */
  415. static int
  416. sock_socket(int family, int type, int protocol)
  417. {
  418.   int i, fd;
  419.   struct socket *sock;
  420.   struct proto_ops *ops;
  421.  
  422.   DPRINTF((net_debug,
  423.     "NET: sock_socket: family = %d, type = %d, protocol = %d\n",
  424.                         family, type, protocol));
  425.  
  426.   /* Locate the correct protocol family. */
  427.   for (i = 0; i < NPROTO; ++i) {
  428.     if (pops[i] == NULL) continue;
  429.     if (pops[i]->family == family) break;
  430.   }
  431.   if (i == NPROTO) {
  432.     DPRINTF((net_debug, "NET: sock_socket: family not found\n"));
  433.     return(-EINVAL);
  434.   }
  435.   ops = pops[i];
  436.  
  437.   /*
  438.    * Check that this is a type that we know how to manipulate and
  439.    * the protocol makes sense here. The family can still reject the
  440.    * protocol later.
  441.    */
  442.   if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
  443.        type != SOCK_SEQPACKET && type != SOCK_RAW &&
  444.        type != SOCK_PACKET) || protocol < 0)
  445.                             return(-EINVAL);
  446.  
  447.   /*
  448.    * allocate the socket and allow the family to set things up. if
  449.    * the protocol is 0, the family is instructed to select an appropriate
  450.    * default.
  451.    */
  452.   if (!(sock = sock_alloc(1))) {
  453.     printk("sock_socket: no more sockets\n");
  454.     return(-EAGAIN);
  455.   }
  456.   sock->type = type;
  457.   sock->ops = ops;
  458.   if ((i = sock->ops->create(sock, protocol)) < 0) {
  459.     sock_release(sock);
  460.     return(i);
  461.   }
  462.  
  463.   if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
  464.     sock_release(sock);
  465.     return(-EINVAL);
  466.   }
  467.  
  468.   return(fd);
  469. }
  470.  
  471.  
  472. static int
  473. sock_socketpair(int family, int type, int protocol, unsigned long usockvec[2])
  474. {
  475.   int fd1, fd2, i;
  476.   struct socket *sock1, *sock2;
  477.   int er;
  478.  
  479.   DPRINTF((net_debug,
  480.     "NET: sock_socketpair: family = %d, type = %d, protocol = %d\n",
  481.                             family, type, protocol));
  482.  
  483.   /*
  484.    * Obtain the first socket and check if the underlying protocol
  485.    * supports the socketpair call.
  486.    */
  487.   if ((fd1 = sock_socket(family, type, protocol)) < 0) return(fd1);
  488.   sock1 = sockfd_lookup(fd1, NULL);
  489.   if (!sock1->ops->socketpair) {
  490.     sys_close(fd1);
  491.     return(-EINVAL);
  492.   }
  493.  
  494.   /* Now grab another socket and try to connect the two together. */
  495.   if ((fd2 = sock_socket(family, type, protocol)) < 0) {
  496.     sys_close(fd1);
  497.     return(-EINVAL);
  498.   }
  499.   sock2 = sockfd_lookup(fd2, NULL);
  500.   if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
  501.     sys_close(fd1);
  502.     sys_close(fd2);
  503.     return(i);
  504.   }
  505.   sock1->conn = sock2;
  506.   sock2->conn = sock1;
  507.   sock1->state = SS_CONNECTED;
  508.   sock2->state = SS_CONNECTED;
  509.  
  510.   er=verify_area(VERIFY_WRITE, usockvec, 2 * sizeof(int));
  511.   if(er)
  512.       return er;
  513.   put_fs_long(fd1, &usockvec[0]);
  514.   put_fs_long(fd2, &usockvec[1]);
  515.  
  516.   return(0);
  517. }
  518.  
  519.  
  520. /*
  521.  * Bind a name to a socket. Nothing much to do here since its
  522.  * the protocol's responsibility to handle the local address.
  523.  */
  524. static int
  525. sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
  526. {
  527.   struct socket *sock;
  528.   int i;
  529.  
  530.   DPRINTF((net_debug, "NET: sock_bind: fd = %d\n", fd));
  531.   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
  532.                                 return(-EBADF);
  533.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  534.   if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
  535.     DPRINTF((net_debug, "NET: sock_bind: bind failed\n"));
  536.     return(i);
  537.   }
  538.   return(0);
  539. }
  540.  
  541.  
  542. /*
  543.  * Perform a listen. Basically, we allow the protocol to do anything
  544.  * necessary for a listen, and if that works, we mark the socket as
  545.  * ready for listening.
  546.  */
  547. static int
  548. sock_listen(int fd, int backlog)
  549. {
  550.   struct socket *sock;
  551.  
  552.   DPRINTF((net_debug, "NET: sock_listen: fd = %d\n", fd));
  553.   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
  554.                                 return(-EBADF);
  555.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  556.   if (sock->state != SS_UNCONNECTED) {
  557.     DPRINTF((net_debug, "NET: sock_listen: socket isn't unconnected\n"));
  558.     return(-EINVAL);
  559.   }
  560.   if (sock->ops && sock->ops->listen) sock->ops->listen(sock, backlog);
  561.   sock->flags |= SO_ACCEPTCON;
  562.   return(0);
  563. }
  564.  
  565.  
  566. /*
  567.  * For accept, we attempt to create a new socket, set up the link
  568.  * with the client, wake up the client, then return the new
  569.  * connected fd.
  570.  */
  571. static int
  572. sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
  573. {
  574.   struct file *file;
  575.   struct socket *sock, *newsock;
  576.   int i;
  577.  
  578.   DPRINTF((net_debug, "NET: sock_accept: fd = %d\n", fd));
  579.   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
  580.                                 return(-EBADF);
  581.   
  582.   if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
  583.   if (sock->state != SS_UNCONNECTED) {
  584.     DPRINTF((net_debug, "NET: sock_accept: socket isn't unconnected\n"));
  585.     return(-EINVAL);
  586.   }
  587.   if (!(sock->flags & SO_ACCEPTCON)) {
  588.     DPRINTF((net_debug,
  589.         "NET: sock_accept: socket not accepting connections!\n"));
  590.     return(-EINVAL);
  591.   }
  592.  
  593.   if (!(newsock = sock_alloc(0))) {
  594.     printk("NET: sock_accept: no more sockets\n");
  595.     return(-EAGAIN);
  596.   }
  597.   newsock->type = sock->type;
  598.   newsock->ops = sock->ops;
  599.   if ((i = sock->ops->dup(newsock, sock)) < 0) {
  600.     sock_release(newsock);
  601.     return(i);
  602.   }
  603.  
  604.   i = newsock->ops->accept(sock, newsock, file->f_flags);
  605.   if ( i < 0) {
  606.     sock_release(newsock);
  607.     return(i);
  608.   }
  609.  
  610.   if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
  611.     sock_release(newsock);
  612.     return(-EINVAL);
  613.   }
  614.  
  615.   DPRINTF((net_debug, "NET: sock_accept: connected socket 0x%x via 0x%x\n",
  616.                             sock, newsock));
  617.  
  618.   if (upeer_sockaddr)
  619.     newsock->ops->getname(newsock, upeer_sockaddr, upeer_addrlen, 1);
  620.  
  621.   return(fd);
  622. }
  623.  
  624.  
  625. /* Attempt to connect to a socket with the server address. */
  626. static int
  627. sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
  628. {
  629.   struct socket *sock;
  630.   struct file *file;
  631.   int i;
  632.  
  633.   DPRINTF((net_debug, "NET: sock_connect: fd = %d\n", fd));
  634.   if (fd < 0 || fd >= NR_OPEN || (file=current->filp[fd]) == NULL)
  635.                                 return(-EBADF);
  636.   
  637.   if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
  638.   switch(sock->state) {
  639.     case SS_UNCONNECTED:
  640.         /* This is ok... continue with connect */
  641.         break;
  642.     case SS_CONNECTED:
  643.         /* Socket is already connected */
  644.         return -EISCONN;
  645.     case SS_CONNECTING:
  646.         /* Not yet connected... we will check this. */
  647.         return(sock->ops->connect(sock, uservaddr,
  648.                       addrlen, file->f_flags));
  649.     default:
  650.         DPRINTF((net_debug,
  651.             "NET: sock_connect: socket not unconnected\n"));
  652.         return(-EINVAL);
  653.   }
  654.   i = sock->ops->connect(sock, uservaddr, addrlen, file->f_flags);
  655.   if (i < 0) {
  656.     DPRINTF((net_debug, "NET: sock_connect: connect failed\n"));
  657.     return(i);
  658.   }
  659.   return(0);
  660. }
  661.  
  662.  
  663. static int
  664. sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
  665. {
  666.   struct socket *sock;
  667.  
  668.   DPRINTF((net_debug, "NET: sock_getsockname: fd = %d\n", fd));
  669.   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
  670.                                 return(-EBADF);
  671.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  672.   return(sock->ops->getname(sock, usockaddr, usockaddr_len, 0));
  673. }
  674.  
  675.  
  676. static int
  677. sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
  678. {
  679.   struct socket *sock;
  680.  
  681.   DPRINTF((net_debug, "NET: sock_getpeername: fd = %d\n", fd));
  682.   if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
  683.             return(-EBADF);
  684.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  685.   return(sock->ops->getname(sock, usockaddr, usockaddr_len, 1));
  686. }
  687.  
  688.  
  689. static int
  690. sock_send(int fd, void * buff, int len, unsigned flags)
  691. {
  692.   struct socket *sock;
  693.   struct file *file;
  694.  
  695.   DPRINTF((net_debug,
  696.     "NET: sock_send(fd = %d, buff = %X, len = %d, flags = %X)\n",
  697.                                    fd, buff, len, flags));
  698.  
  699.   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
  700.                                 return(-EBADF);
  701.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  702.  
  703.   return(sock->ops->send(sock, buff, len, (file->f_flags & O_NONBLOCK), flags));
  704. }
  705.  
  706.  
  707. static int
  708. sock_sendto(int fd, void * buff, int len, unsigned flags,
  709.        struct sockaddr *addr, int addr_len)
  710. {
  711.   struct socket *sock;
  712.   struct file *file;
  713.  
  714.   DPRINTF((net_debug,
  715.     "NET: sock_sendto(fd = %d, buff = %X, len = %d, flags = %X,"
  716.      " addr=%X, alen = %d\n", fd, buff, len, flags, addr, addr_len));
  717.  
  718.   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
  719.                                 return(-EBADF);
  720.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  721.  
  722.   return(sock->ops->sendto(sock, buff, len, (file->f_flags & O_NONBLOCK),
  723.                flags, addr, addr_len));
  724. }
  725.  
  726.  
  727. static int
  728. sock_recv(int fd, void * buff, int len, unsigned flags)
  729. {
  730.   struct socket *sock;
  731.   struct file *file;
  732.  
  733.   DPRINTF((net_debug,
  734.     "NET: sock_recv(fd = %d, buff = %X, len = %d, flags = %X)\n",
  735.                             fd, buff, len, flags));
  736.  
  737.   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
  738.                                 return(-EBADF);
  739.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  740.  
  741.   return(sock->ops->recv(sock, buff, len,(file->f_flags & O_NONBLOCK), flags));
  742. }
  743.  
  744.  
  745. static int
  746. sock_recvfrom(int fd, void * buff, int len, unsigned flags,
  747.          struct sockaddr *addr, int *addr_len)
  748. {
  749.   struct socket *sock;
  750.   struct file *file;
  751.  
  752.   DPRINTF((net_debug,
  753.     "NET: sock_recvfrom(fd = %d, buff = %X, len = %d, flags = %X,"
  754.     " addr=%X, alen=%X\n", fd, buff, len, flags, addr, addr_len));
  755.  
  756.   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
  757.                                 return(-EBADF);
  758.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  759.  
  760.   return(sock->ops->recvfrom(sock, buff, len, (file->f_flags & O_NONBLOCK),
  761.                  flags, addr, addr_len));
  762. }
  763.  
  764.  
  765. static int
  766. sock_setsockopt(int fd, int level, int optname, char *optval, int optlen)
  767. {
  768.   struct socket *sock;
  769.   struct file *file;
  770.     
  771.   DPRINTF((net_debug, "NET: sock_setsockopt(fd=%d, level=%d, optname=%d,\n",
  772.                             fd, level, optname));
  773.   DPRINTF((net_debug, "                     optval = %X, optlen = %d)\n",
  774.                             optval, optlen));
  775.  
  776.   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
  777.                                 return(-EBADF);
  778.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  779.  
  780.   return(sock->ops->setsockopt(sock, level, optname, optval, optlen));
  781. }
  782.  
  783.  
  784. static int
  785. sock_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
  786. {
  787.   struct socket *sock;
  788.   struct file *file;
  789.  
  790.   DPRINTF((net_debug, "NET: sock_getsockopt(fd=%d, level=%d, optname=%d,\n",
  791.                         fd, level, optname));
  792.   DPRINTF((net_debug, "                     optval = %X, optlen = %X)\n",
  793.                         optval, optlen));
  794.  
  795.   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
  796.                                 return(-EBADF);
  797.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  798.         
  799.   if (!sock->ops || !sock->ops->getsockopt) return(0);
  800.   return(sock->ops->getsockopt(sock, level, optname, optval, optlen));
  801. }
  802.  
  803.  
  804. static int
  805. sock_shutdown(int fd, int how)
  806. {
  807.   struct socket *sock;
  808.   struct file *file;
  809.  
  810.   DPRINTF((net_debug, "NET: sock_shutdown(fd = %d, how = %d)\n", fd, how));
  811.  
  812.   if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
  813.                                 return(-EBADF);
  814.  
  815.   if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
  816.  
  817.   return(sock->ops->shutdown(sock, how));
  818. }
  819.  
  820.  
  821. int
  822. sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
  823. {
  824.   struct socket *sock;
  825.  
  826.   sock = socki_lookup (filp->f_inode);
  827.   if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
  828.                 return(sock->ops->fcntl(sock, cmd, arg));
  829.   return(-EINVAL);
  830. }
  831.  
  832.  
  833. /*
  834.  * System call vectors. Since I (RIB) want to rewrite sockets as streams,
  835.  * we have this level of indirection. Not a lot of overhead, since more of
  836.  * the work is done via read/write/select directly.
  837.  */
  838. asmlinkage int
  839. sys_socketcall(int call, unsigned long *args)
  840. {
  841.   int er;
  842.   switch(call) {
  843.     case SYS_SOCKET:
  844.         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
  845.         if(er)
  846.             return er;
  847.         return(sock_socket(get_fs_long(args+0),
  848.                    get_fs_long(args+1),
  849.                    get_fs_long(args+2)));
  850.     case SYS_BIND:
  851.         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
  852.         if(er)
  853.             return er;
  854.         return(sock_bind(get_fs_long(args+0),
  855.                  (struct sockaddr *)get_fs_long(args+1),
  856.                  get_fs_long(args+2)));
  857.     case SYS_CONNECT:
  858.         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
  859.         if(er)
  860.             return er;
  861.         return(sock_connect(get_fs_long(args+0),
  862.                     (struct sockaddr *)get_fs_long(args+1),
  863.                     get_fs_long(args+2)));
  864.     case SYS_LISTEN:
  865.         er=verify_area(VERIFY_READ, args, 2 * sizeof(long));
  866.         if(er)
  867.             return er;
  868.         return(sock_listen(get_fs_long(args+0),
  869.                    get_fs_long(args+1)));
  870.     case SYS_ACCEPT:
  871.         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
  872.         if(er)
  873.             return er;
  874.         return(sock_accept(get_fs_long(args+0),
  875.                    (struct sockaddr *)get_fs_long(args+1),
  876.                    (int *)get_fs_long(args+2)));
  877.     case SYS_GETSOCKNAME:
  878.         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
  879.         if(er)
  880.             return er;
  881.         return(sock_getsockname(get_fs_long(args+0),
  882.                     (struct sockaddr *)get_fs_long(args+1),
  883.                     (int *)get_fs_long(args+2)));
  884.     case SYS_GETPEERNAME:
  885.         er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
  886.         if(er)
  887.             return er;
  888.         return(sock_getpeername(get_fs_long(args+0),
  889.                     (struct sockaddr *)get_fs_long(args+1),
  890.                     (int *)get_fs_long(args+2)));
  891.     case SYS_SOCKETPAIR:
  892.         er=verify_area(VERIFY_READ, args, 4 * sizeof(long));
  893.         if(er)
  894.             return er;
  895.         return(sock_socketpair(get_fs_long(args+0),
  896.                        get_fs_long(args+1),
  897.                        get_fs_long(args+2),
  898.                        (unsigned long *)get_fs_long(args+3)));
  899.     case SYS_SEND:
  900.         er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
  901.         if(er)
  902.             return er;
  903.         return(sock_send(get_fs_long(args+0),
  904.                  (void *)get_fs_long(args+1),
  905.                  get_fs_long(args+2),
  906.                  get_fs_long(args+3)));
  907.     case SYS_SENDTO:
  908.         er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
  909.         if(er)
  910.             return er;
  911.         return(sock_sendto(get_fs_long(args+0),
  912.                    (void *)get_fs_long(args+1),
  913.                    get_fs_long(args+2),
  914.                    get_fs_long(args+3),
  915.                    (struct sockaddr *)get_fs_long(args+4),
  916.                    get_fs_long(args+5)));
  917.     case SYS_RECV:
  918.         er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
  919.         if(er)
  920.             return er;
  921.         return(sock_recv(get_fs_long(args+0),
  922.                  (void *)get_fs_long(args+1),
  923.                  get_fs_long(args+2),
  924.                  get_fs_long(args+3)));
  925.     case SYS_RECVFROM:
  926.         er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
  927.         if(er)
  928.             return er;
  929.         return(sock_recvfrom(get_fs_long(args+0),
  930.                      (void *)get_fs_long(args+1),
  931.                      get_fs_long(args+2),
  932.                      get_fs_long(args+3),
  933.                      (struct sockaddr *)get_fs_long(args+4),
  934.                      (int *)get_fs_long(args+5)));
  935.     case SYS_SHUTDOWN:
  936.         er=verify_area(VERIFY_READ, args, 2* sizeof(unsigned long));
  937.         if(er)
  938.             return er;
  939.         return(sock_shutdown(get_fs_long(args+0),
  940.                      get_fs_long(args+1)));
  941.     case SYS_SETSOCKOPT:
  942.         er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
  943.         if(er)
  944.             return er;
  945.         return(sock_setsockopt(get_fs_long(args+0),
  946.                        get_fs_long(args+1),
  947.                        get_fs_long(args+2),
  948.                        (char *)get_fs_long(args+3),
  949.                        get_fs_long(args+4)));
  950.     case SYS_GETSOCKOPT:
  951.         er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
  952.         if(er)
  953.             return er;
  954.         return(sock_getsockopt(get_fs_long(args+0),
  955.                        get_fs_long(args+1),
  956.                        get_fs_long(args+2),
  957.                        (char *)get_fs_long(args+3),
  958.                        (int *)get_fs_long(args+4)));
  959.     default:
  960.         return(-EINVAL);
  961.   }
  962. }
  963.  
  964.  
  965. static int
  966. net_ioctl(unsigned int cmd, unsigned long arg)
  967. {
  968.   int er;
  969.   switch(cmd) {
  970.     case DDIOCSDBG:
  971.         er=verify_area(VERIFY_READ, (void *)arg, sizeof(long));
  972.         if(er)
  973.             return er;
  974.         net_debug = get_fs_long((long *)arg);
  975.         if (net_debug != 0 && net_debug != 1) {
  976.             net_debug = 0;
  977.             return(-EINVAL);
  978.         }
  979.         return(0);
  980.     default:
  981.         return(-EINVAL);
  982.   }
  983.   /*NOTREACHED*/
  984.   return(0);
  985. }
  986.  
  987.  
  988. /*
  989.  * Handle the IOCTL system call for the NET devices.  This basically
  990.  * means I/O control for the SOCKET layer (future expansions could be
  991.  * a variable number of socket table entries, et al), and for the more
  992.  * general protocols like ARP.  The latter currently lives in the INET
  993.  * module, so we have to get ugly a tiny little bit.  Later... -FvK
  994.  */
  995. static int
  996. net_fioctl(struct inode *inode, struct file *file,
  997.        unsigned int cmd, unsigned long arg)
  998. {
  999.   extern int arp_ioctl(unsigned int, void *);
  1000.  
  1001.   /* Dispatch on the minor device. */
  1002.   switch(MINOR(inode->i_rdev)) {
  1003.     case 0:        /* NET (SOCKET) */
  1004.         DPRINTF((net_debug, "NET: SOCKET level I/O control request.\n"));
  1005.         return(net_ioctl(cmd, arg));
  1006. #ifdef CONFIG_INET
  1007.     case 1:        /* ARP */
  1008.         DPRINTF((net_debug, "NET: ARP level I/O control request.\n"));
  1009.         return(arp_ioctl(cmd, (void *) arg));
  1010. #endif
  1011.     default:
  1012.         return(-ENODEV);
  1013.   }
  1014.   /*NOTREACHED*/
  1015.   return(-EINVAL);
  1016. }
  1017.  
  1018.  
  1019. static struct file_operations net_fops = {
  1020.   NULL,        /* LSEEK    */
  1021.   NULL,        /* READ        */
  1022.   NULL,        /* WRITE    */
  1023.   NULL,        /* READDIR    */
  1024.   NULL,        /* SELECT    */
  1025.   net_fioctl,    /* IOCTL    */
  1026.   NULL,        /* MMAP        */
  1027.   NULL,        /* OPEN        */
  1028.   NULL        /* CLOSE    */
  1029. };
  1030.  
  1031.  
  1032. /*
  1033.  * This function is called by a protocol handler that wants to
  1034.  * advertise its address family, and have it linked into the
  1035.  * SOCKET module.
  1036.  */
  1037. int
  1038. sock_register(int family, struct proto_ops *ops)
  1039. {
  1040.   int i;
  1041.  
  1042.   cli();
  1043.   for(i = 0; i < NPROTO; i++) {
  1044.     if (pops[i] != NULL) continue;
  1045.     pops[i] = ops;
  1046.     pops[i]->family = family;
  1047.     sti();
  1048.     DPRINTF((net_debug, "NET: Installed protocol %d in slot %d (0x%X)\n",
  1049.                         family, i, (long)ops));
  1050.     return(i);
  1051.   }
  1052.   sti();
  1053.   return(-ENOMEM);
  1054. }
  1055.  
  1056.  
  1057. void
  1058. sock_init(void)
  1059. {
  1060.   struct socket *sock;
  1061.   int i;
  1062.  
  1063.   /* Set up our SOCKET VFS major device. */
  1064.   if (register_chrdev(SOCKET_MAJOR, "socket", &net_fops) < 0) {
  1065.     printk("NET: cannot register major device %d!\n", SOCKET_MAJOR);
  1066.     return;
  1067.   }
  1068.  
  1069.   /* Release all sockets. */
  1070.   for (sock = sockets; sock <= last_socket; ++sock) sock->state = SS_FREE;
  1071.  
  1072.   /* Initialize all address (protocol) families. */
  1073.   for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
  1074.  
  1075.   /* Initialize the DDI module. */
  1076.   ddi_init();
  1077.  
  1078.   /* Initialize the ARP module. */
  1079. #if 0
  1080.   arp_init();
  1081. #endif
  1082. }
  1083.